package top.chengdongqing.mishop.common.security

import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity
import org.springframework.security.config.annotation.web.builders.HttpSecurity
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity
import org.springframework.security.config.http.SessionCreationPolicy
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder
import org.springframework.security.crypto.password.PasswordEncoder
import org.springframework.security.web.SecurityFilterChain
import org.springframework.security.web.authentication.www.BasicAuthenticationEntryPoint
import org.springframework.web.cors.CorsConfiguration
import org.springframework.web.cors.UrlBasedCorsConfigurationSource

@Configuration
@EnableWebSecurity
@EnableMethodSecurity
class SecurityConfigurer(
    private val jwtAuthenticationFilter: JwtAuthenticationFilter
) {

    @Bean
    fun securityFilterChain(httpSecurity: HttpSecurity): SecurityFilterChain {
        return httpSecurity
            .csrf { it.disable() }
            .cors {
                val configuration = CorsConfiguration()
                configuration.allowedOriginPatterns = listOf("http://localhost:*")
                configuration.allowedMethods = listOf("*")
                configuration.allowedHeaders = listOf("*")
                val source = UrlBasedCorsConfigurationSource()
                source.registerCorsConfiguration("/**", configuration)
                it.configurationSource(source)
            }
            .sessionManagement {
                it.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
            }
            .authorizeHttpRequests {
                it.requestMatchers("/orders/payment/callback/**")
                    .permitAll()
                    .requestMatchers(
                        "/shopping-cart/**",
                        "/orders/**",
                        "/users/**"
                    )
                    .authenticated()
                    .anyRequest()
                    .permitAll()
            }
            .addFilter(jwtAuthenticationFilter)
            .exceptionHandling { handle -> handle.authenticationEntryPoint(BasicAuthenticationEntryPoint()) }
            .build()
    }

    @Bean
    fun passwordEncoder(): PasswordEncoder {
        return BCryptPasswordEncoder()
    }
}